
#import "Sprite.h"
#import "GameManager.h"

@implementation Sprite

-(id) init {    
    if (self = [super init]) { 
        textureID = -1;
        pos.x = 0;
        pos.y = 0;
        pos.z = 0;
        speed.x = 0;
        speed.y = 0;
        speed.z = 0; 
        rotation.x = 0;
        rotation.y = 0;
        rotation.z = 0;
        angle = 0;
        angleStep = 0;
        radius = 1;
        type = -1;
        active = true;
        autoDestroy = true;
        [self additionalSetup];
    }
    return self;        
}

- (void) additionalSetup {
    //Override for individual setup
}

- (int) getType {
    return type;
}

- (Vertex) getPos {
    return pos;
}

- (void) setPos: (Vertex) newPos {
    pos = newPos;
}

- (float) getRadius {
    return radius;
}

- (void) setSpeed: (Vertex) newSpeed {
    speed = newSpeed;
}

- (void) setRotationStep: (float) newAngleStep 
              aroundAxis: (Vertex) newRotation {
    angleStep = newAngleStep;
    rotation = newRotation;
}

- (bool) isActive {
    return active;
}

- (void) draw {   
    if (active) {        
        [self renderSprite]; 
    }    
}  

- (void) renderSprite {         
    glEnable(GL_NORMALIZE);     
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
            
    if (textureID > 0) {
        glEnable(GL_TEXTURE_2D); 
        glBindTexture(GL_TEXTURE_2D, textureID);     
        glTexCoordPointer(3, GL_FLOAT, 0, textureCoords);
    }
    glVertexPointer(3, GL_FLOAT, 0, vertices);
    glNormalPointer(GL_FLOAT, 0, normals);
    
    [self setColor];
    
    glPushMatrix();  
    [self move];            
    if (facesLength == 0) {
        glDrawArrays(GL_TRIANGLE_STRIP, 0, verticesLength/3);
    } else {
        glDrawElements(GL_TRIANGLES, facesLength, GL_UNSIGNED_SHORT, faces);
    }    
    glPopMatrix();
    
    glDisable(GL_TEXTURE_2D);    
    glDisable(GL_NORMALIZE);     
    glDisable(GL_CULL_FACE);
}

- (void) setColor {
    //Override for individual colors
    glColor4f(1, 1, 1, 1);
}

- (void) move {        
    pos.x += speed.x;
    pos.y += speed.y;
    pos.z += speed.z;    
    angle += angleStep;
    
    glTranslatef(pos.x, pos.y, pos.z);
    glRotatef(angle, rotation.x, rotation.y, rotation.z);     

    if (autoDestroy) {
        Player * p = [[GameManager getInstance] getPlayer];
        Vertex posPlayer = [p getPos]; 
        if (pos.z < posPlayer.z) { 
            active = false;    
        }    
    }  
}

- (void) hit {
    //Override for individual collision handling
    active = false;
}

- (bool) checkColWithSprite: (Sprite *) sprite {    
       
    Vertex v = [sprite getPos];
    float x1 = v.x;
    float y1 = v.y;
    float z1 = v.z;
    float r1 = [sprite getRadius];
    
    float x2 = pos.x;
    float y2 = pos.y;
    float z2 = pos.z;
    float r2 = radius;
        
    if ( ((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) + (z2 - z1) * (z2 - z1))  
        < (r1 + r2) * (r1 + r2) ) {
        return true;
    }
         
    return false;
}

- (void) setVertices: (GLfloat *) verticesObjData
                size: (int) sizeVerts 
        setTexCoords: (GLfloat *) textureCoordsObjData
                size: (int) sizeTex
          setNormals: (GLfloat *) normalsObjData
                size: (int) sizeNorms
            setFaces: (GLushort *) facesObjData
                size: (int) sizeFaces {
    
    verticesLength = sizeVerts / sizeof(GLfloat);
    facesLength = sizeFaces / sizeof(GLushort);
    
    vertices = malloc (sizeVerts);
    memcpy(vertices, verticesObjData, sizeVerts);
    
    textureCoords = malloc (sizeTex);
    memcpy(textureCoords, textureCoordsObjData, sizeTex);
    
    normals = malloc (sizeNorms);
    memcpy(normals, normalsObjData, sizeNorms);
    
    faces = malloc (sizeFaces);
    memcpy(faces, facesObjData, sizeFaces);
}

- (void) dealloc {
    [super dealloc];
}

@end
